-
Notifications
You must be signed in to change notification settings - Fork 14.4k
DAG: Fall back to separate sin and cos when softening sincos #147468
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DAG: Fall back to separate sin and cos when softening sincos #147468
Conversation
This stack of pull requests is managed by Graphite. Learn more about stacking. |
@llvm/pr-subscribers-backend-webassembly @llvm/pr-subscribers-llvm-selectiondag Author: Matt Arsenault (arsenm) ChangesFix asserting in the error case. Full diff: https://github.com/llvm/llvm-project/pull/147468.diff 6 Files Affected:
diff --git a/llvm/include/llvm/CodeGen/RuntimeLibcallUtil.h b/llvm/include/llvm/CodeGen/RuntimeLibcallUtil.h
index 451459eda25e9..f865b8c1583f8 100644
--- a/llvm/include/llvm/CodeGen/RuntimeLibcallUtil.h
+++ b/llvm/include/llvm/CodeGen/RuntimeLibcallUtil.h
@@ -68,6 +68,14 @@ LLVM_ABI Libcall getLDEXP(EVT RetVT);
/// UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getFREXP(EVT RetVT);
+/// Return the SIN_* value for the given types, or UNKNOWN_LIBCALL if there is
+/// none.
+LLVM_ABI Libcall getSIN(EVT RetVT);
+
+/// Return the COS_* value for the given types, or UNKNOWN_LIBCALL if there is
+/// none.
+LLVM_ABI Libcall getCOS(EVT RetVT);
+
/// getSINCOS - Return the SINCOS_* value for the given types, or
/// UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getSINCOS(EVT RetVT);
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
index 14bbf6a2f5220..2cad36eff9c88 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
@@ -794,7 +794,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FFREXP(SDNode *N) {
return ReturnVal;
}
-SDValue DAGTypeLegalizer::SoftenFloatRes_UnaryWithTwoFPResults(
+bool DAGTypeLegalizer::SoftenFloatRes_UnaryWithTwoFPResults(
SDNode *N, RTLIB::Libcall LC, std::optional<unsigned> CallRetResNo) {
assert(!N->isStrictFPOpcode() && "strictfp not implemented");
EVT VT = N->getValueType(0);
@@ -803,7 +803,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_UnaryWithTwoFPResults(
"expected both return values to have the same type");
if (!TLI.getLibcallName(LC))
- return SDValue();
+ return false;
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
@@ -849,17 +849,46 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_UnaryWithTwoFPResults(
SetSoftenedFloat(SDValue(N, ResNum), CreateStackLoad(SlackSlot));
}
- return SDValue();
+ return true;
}
SDValue DAGTypeLegalizer::SoftenFloatRes_FSINCOS(SDNode *N) {
- return SoftenFloatRes_UnaryWithTwoFPResults(
- N, RTLIB::getSINCOS(N->getValueType(0)));
+ EVT VT = N->getValueType(0);
+ if (SoftenFloatRes_UnaryWithTwoFPResults(N, RTLIB::getSINCOS(VT)))
+ return SDValue();
+
+ // Fall back on softening the separate sin and cos calls if available.
+ RTLIB::Libcall SinLC = RTLIB::getSIN(VT);
+ RTLIB::Libcall CosLC = RTLIB::getCOS(VT);
+
+ SDValue SoftSin, SoftCos;
+ if (!TLI.getLibcallName(SinLC) || !TLI.getLibcallName(CosLC)) {
+ DAG.getContext()->emitError("do not know how to soften fsincos");
+
+ EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
+ SoftSin = SoftCos = DAG.getPOISON(NVT);
+ } else {
+ SoftSin = SoftenFloatRes_Unary(N, SinLC);
+ SoftCos = SoftenFloatRes_Unary(N, CosLC);
+ }
+
+ SetSoftenedFloat(SDValue(N, 0), SoftSin);
+ SetSoftenedFloat(SDValue(N, 1), SoftCos);
+ return SDValue();
}
SDValue DAGTypeLegalizer::SoftenFloatRes_FMODF(SDNode *N) {
- return SoftenFloatRes_UnaryWithTwoFPResults(
- N, RTLIB::getMODF(N->getValueType(0)), /*CallRetResNo=*/0);
+ EVT VT = N->getValueType(0);
+ if (SoftenFloatRes_UnaryWithTwoFPResults(N, RTLIB::getMODF(VT),
+ /*CallRetResNo=*/0))
+ return SDValue();
+
+ EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
+ DAG.getContext()->emitError("do not know how to soften fmodf");
+ SDValue Poison = DAG.getPOISON(NVT);
+ SetSoftenedFloat(SDValue(N, 0), Poison);
+ SetSoftenedFloat(SDValue(N, 1), Poison);
+ return SDValue();
}
SDValue DAGTypeLegalizer::SoftenFloatRes_FREM(SDNode *N) {
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
index 8643ae9d78159..9b537248d4ab4 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
@@ -564,7 +564,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
// Convert Float Results to Integer.
void SoftenFloatResult(SDNode *N, unsigned ResNo);
SDValue SoftenFloatRes_Unary(SDNode *N, RTLIB::Libcall LC);
- SDValue SoftenFloatRes_UnaryWithTwoFPResults(
+ bool SoftenFloatRes_UnaryWithTwoFPResults(
SDNode *N, RTLIB::Libcall LC, std::optional<unsigned> CallRetResNo = {});
SDValue SoftenFloatRes_Binary(SDNode *N, RTLIB::Libcall LC);
SDValue SoftenFloatRes_MERGE_VALUES(SDNode *N, unsigned ResNo);
diff --git a/llvm/lib/CodeGen/TargetLoweringBase.cpp b/llvm/lib/CodeGen/TargetLoweringBase.cpp
index 4f722005f4056..06933c910cd5e 100644
--- a/llvm/lib/CodeGen/TargetLoweringBase.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringBase.cpp
@@ -410,6 +410,14 @@ RTLIB::Libcall RTLIB::getFREXP(EVT RetVT) {
FREXP_PPCF128);
}
+RTLIB::Libcall RTLIB::getSIN(EVT RetVT) {
+ return getFPLibCall(RetVT, SIN_F32, SIN_F64, SIN_F80, SIN_F128, SIN_PPCF128);
+}
+
+RTLIB::Libcall RTLIB::getCOS(EVT RetVT) {
+ return getFPLibCall(RetVT, COS_F32, COS_F64, COS_F80, COS_F128, COS_PPCF128);
+}
+
RTLIB::Libcall RTLIB::getSINCOS(EVT RetVT) {
return getFPLibCall(RetVT, SINCOS_F32, SINCOS_F64, SINCOS_F80, SINCOS_F128,
SINCOS_PPCF128);
diff --git a/llvm/test/CodeGen/AVR/sincos-soften-error.ll b/llvm/test/CodeGen/AVR/sincos-soften-error.ll
new file mode 100644
index 0000000000000..85f5aabb4e966
--- /dev/null
+++ b/llvm/test/CodeGen/AVR/sincos-soften-error.ll
@@ -0,0 +1,9 @@
+; RUN: not llc -mtriple=avr -filetype=null %s 2>&1 | FileCheck %s
+
+; CHECK: error: do not know how to soften fsincos
+define { double, double } @test_sincos_f64(double %a) #0 {
+ %result = call { double, double } @llvm.sincos.f64(double %a)
+ ret { double, double } %result
+}
+
+attributes #0 = { nounwind }
diff --git a/llvm/test/CodeGen/WebAssembly/llvm.sincos.ll b/llvm/test/CodeGen/WebAssembly/llvm.sincos.ll
index e01a8c66507b3..b5509341f0cec 100644
--- a/llvm/test/CodeGen/WebAssembly/llvm.sincos.ll
+++ b/llvm/test/CodeGen/WebAssembly/llvm.sincos.ll
@@ -485,16 +485,232 @@ define { <2 x double>, <2 x double> } @test_sincos_v2f64(<2 x double> %a) #0 {
ret { <2 x double>, <2 x double> } %result
}
-; ; FIXME: Asserts
-; define { fp128, fp128 } @test_sincos_f128(fp128 %a) #0 {
-; %result = call { fp128, fp128 } @llvm.sincos.f128(fp128 %a)
-; ret { fp128, fp128 } %result
-; }
+define { fp128, fp128 } @test_sincos_f128(fp128 %a) #0 {
+; WASM32-LABEL: test_sincos_f128:
+; WASM32: .functype test_sincos_f128 (i32, i64, i64) -> ()
+; WASM32-NEXT: .local i32
+; WASM32-NEXT: # %bb.0:
+; WASM32-NEXT: global.get __stack_pointer
+; WASM32-NEXT: i32.const 32
+; WASM32-NEXT: i32.sub
+; WASM32-NEXT: local.tee 3
+; WASM32-NEXT: global.set __stack_pointer
+; WASM32-NEXT: local.get 3
+; WASM32-NEXT: local.get 1
+; WASM32-NEXT: local.get 2
+; WASM32-NEXT: call cosl
+; WASM32-NEXT: local.get 3
+; WASM32-NEXT: i32.const 16
+; WASM32-NEXT: i32.add
+; WASM32-NEXT: local.get 1
+; WASM32-NEXT: local.get 2
+; WASM32-NEXT: call sinl
+; WASM32-NEXT: local.get 0
+; WASM32-NEXT: local.get 3
+; WASM32-NEXT: i64.load 8
+; WASM32-NEXT: i64.store 24
+; WASM32-NEXT: local.get 0
+; WASM32-NEXT: local.get 3
+; WASM32-NEXT: i64.load 0
+; WASM32-NEXT: i64.store 16
+; WASM32-NEXT: local.get 0
+; WASM32-NEXT: local.get 3
+; WASM32-NEXT: i64.load 24
+; WASM32-NEXT: i64.store 8
+; WASM32-NEXT: local.get 0
+; WASM32-NEXT: local.get 3
+; WASM32-NEXT: i64.load 16
+; WASM32-NEXT: i64.store 0
+; WASM32-NEXT: local.get 3
+; WASM32-NEXT: i32.const 32
+; WASM32-NEXT: i32.add
+; WASM32-NEXT: global.set __stack_pointer
+; WASM32-NEXT: # fallthrough-return
+;
+; WASM64-LABEL: test_sincos_f128:
+; WASM64: .functype test_sincos_f128 (i64, i64, i64) -> ()
+; WASM64-NEXT: .local i64
+; WASM64-NEXT: # %bb.0:
+; WASM64-NEXT: global.get __stack_pointer
+; WASM64-NEXT: i64.const 32
+; WASM64-NEXT: i64.sub
+; WASM64-NEXT: local.tee 3
+; WASM64-NEXT: global.set __stack_pointer
+; WASM64-NEXT: local.get 3
+; WASM64-NEXT: local.get 1
+; WASM64-NEXT: local.get 2
+; WASM64-NEXT: call cosl
+; WASM64-NEXT: local.get 3
+; WASM64-NEXT: i64.const 16
+; WASM64-NEXT: i64.add
+; WASM64-NEXT: local.get 1
+; WASM64-NEXT: local.get 2
+; WASM64-NEXT: call sinl
+; WASM64-NEXT: local.get 0
+; WASM64-NEXT: local.get 3
+; WASM64-NEXT: i64.load 8
+; WASM64-NEXT: i64.store 24
+; WASM64-NEXT: local.get 0
+; WASM64-NEXT: local.get 3
+; WASM64-NEXT: i64.load 0
+; WASM64-NEXT: i64.store 16
+; WASM64-NEXT: local.get 0
+; WASM64-NEXT: local.get 3
+; WASM64-NEXT: i64.load 24
+; WASM64-NEXT: i64.store 8
+; WASM64-NEXT: local.get 0
+; WASM64-NEXT: local.get 3
+; WASM64-NEXT: i64.load 16
+; WASM64-NEXT: i64.store 0
+; WASM64-NEXT: local.get 3
+; WASM64-NEXT: i64.const 32
+; WASM64-NEXT: i64.add
+; WASM64-NEXT: global.set __stack_pointer
+; WASM64-NEXT: # fallthrough-return
+ %result = call { fp128, fp128 } @llvm.sincos.f128(fp128 %a)
+ ret { fp128, fp128 } %result
+}
-; ; FIXME: Asserts
-; define { <2 x fp128>, <2 x fp128> } @test_sincos_v2f128(<2 x fp128> %a) #0 {
-; %result = call { <2 x fp128>, <2 x fp128> } @llvm.sincos.v2f128(<2 x fp128> %a)
-; ret { <2 x fp128>, <2 x fp128> } %result
-; }
+define { <2 x fp128>, <2 x fp128> } @test_sincos_v2f128(<2 x fp128> %a) #0 {
+; WASM32-LABEL: test_sincos_v2f128:
+; WASM32: .functype test_sincos_v2f128 (i32, i64, i64, i64, i64) -> ()
+; WASM32-NEXT: .local i32
+; WASM32-NEXT: # %bb.0:
+; WASM32-NEXT: global.get __stack_pointer
+; WASM32-NEXT: i32.const 64
+; WASM32-NEXT: i32.sub
+; WASM32-NEXT: local.tee 5
+; WASM32-NEXT: global.set __stack_pointer
+; WASM32-NEXT: local.get 5
+; WASM32-NEXT: i32.const 32
+; WASM32-NEXT: i32.add
+; WASM32-NEXT: local.get 3
+; WASM32-NEXT: local.get 4
+; WASM32-NEXT: call cosl
+; WASM32-NEXT: local.get 5
+; WASM32-NEXT: local.get 1
+; WASM32-NEXT: local.get 2
+; WASM32-NEXT: call cosl
+; WASM32-NEXT: local.get 5
+; WASM32-NEXT: i32.const 48
+; WASM32-NEXT: i32.add
+; WASM32-NEXT: local.get 3
+; WASM32-NEXT: local.get 4
+; WASM32-NEXT: call sinl
+; WASM32-NEXT: local.get 5
+; WASM32-NEXT: i32.const 16
+; WASM32-NEXT: i32.add
+; WASM32-NEXT: local.get 1
+; WASM32-NEXT: local.get 2
+; WASM32-NEXT: call sinl
+; WASM32-NEXT: local.get 0
+; WASM32-NEXT: local.get 5
+; WASM32-NEXT: i64.load 40
+; WASM32-NEXT: i64.store 56
+; WASM32-NEXT: local.get 0
+; WASM32-NEXT: local.get 5
+; WASM32-NEXT: i64.load 32
+; WASM32-NEXT: i64.store 48
+; WASM32-NEXT: local.get 0
+; WASM32-NEXT: local.get 5
+; WASM32-NEXT: i64.load 8
+; WASM32-NEXT: i64.store 40
+; WASM32-NEXT: local.get 0
+; WASM32-NEXT: local.get 5
+; WASM32-NEXT: i64.load 0
+; WASM32-NEXT: i64.store 32
+; WASM32-NEXT: local.get 0
+; WASM32-NEXT: local.get 5
+; WASM32-NEXT: i64.load 56
+; WASM32-NEXT: i64.store 24
+; WASM32-NEXT: local.get 0
+; WASM32-NEXT: local.get 5
+; WASM32-NEXT: i64.load 48
+; WASM32-NEXT: i64.store 16
+; WASM32-NEXT: local.get 0
+; WASM32-NEXT: local.get 5
+; WASM32-NEXT: i64.load 24
+; WASM32-NEXT: i64.store 8
+; WASM32-NEXT: local.get 0
+; WASM32-NEXT: local.get 5
+; WASM32-NEXT: i64.load 16
+; WASM32-NEXT: i64.store 0
+; WASM32-NEXT: local.get 5
+; WASM32-NEXT: i32.const 64
+; WASM32-NEXT: i32.add
+; WASM32-NEXT: global.set __stack_pointer
+; WASM32-NEXT: # fallthrough-return
+;
+; WASM64-LABEL: test_sincos_v2f128:
+; WASM64: .functype test_sincos_v2f128 (i64, i64, i64, i64, i64) -> ()
+; WASM64-NEXT: .local i64
+; WASM64-NEXT: # %bb.0:
+; WASM64-NEXT: global.get __stack_pointer
+; WASM64-NEXT: i64.const 64
+; WASM64-NEXT: i64.sub
+; WASM64-NEXT: local.tee 5
+; WASM64-NEXT: global.set __stack_pointer
+; WASM64-NEXT: local.get 5
+; WASM64-NEXT: i64.const 32
+; WASM64-NEXT: i64.add
+; WASM64-NEXT: local.get 3
+; WASM64-NEXT: local.get 4
+; WASM64-NEXT: call cosl
+; WASM64-NEXT: local.get 5
+; WASM64-NEXT: local.get 1
+; WASM64-NEXT: local.get 2
+; WASM64-NEXT: call cosl
+; WASM64-NEXT: local.get 5
+; WASM64-NEXT: i64.const 48
+; WASM64-NEXT: i64.add
+; WASM64-NEXT: local.get 3
+; WASM64-NEXT: local.get 4
+; WASM64-NEXT: call sinl
+; WASM64-NEXT: local.get 5
+; WASM64-NEXT: i64.const 16
+; WASM64-NEXT: i64.add
+; WASM64-NEXT: local.get 1
+; WASM64-NEXT: local.get 2
+; WASM64-NEXT: call sinl
+; WASM64-NEXT: local.get 0
+; WASM64-NEXT: local.get 5
+; WASM64-NEXT: i64.load 40
+; WASM64-NEXT: i64.store 56
+; WASM64-NEXT: local.get 0
+; WASM64-NEXT: local.get 5
+; WASM64-NEXT: i64.load 32
+; WASM64-NEXT: i64.store 48
+; WASM64-NEXT: local.get 0
+; WASM64-NEXT: local.get 5
+; WASM64-NEXT: i64.load 8
+; WASM64-NEXT: i64.store 40
+; WASM64-NEXT: local.get 0
+; WASM64-NEXT: local.get 5
+; WASM64-NEXT: i64.load 0
+; WASM64-NEXT: i64.store 32
+; WASM64-NEXT: local.get 0
+; WASM64-NEXT: local.get 5
+; WASM64-NEXT: i64.load 56
+; WASM64-NEXT: i64.store 24
+; WASM64-NEXT: local.get 0
+; WASM64-NEXT: local.get 5
+; WASM64-NEXT: i64.load 48
+; WASM64-NEXT: i64.store 16
+; WASM64-NEXT: local.get 0
+; WASM64-NEXT: local.get 5
+; WASM64-NEXT: i64.load 24
+; WASM64-NEXT: i64.store 8
+; WASM64-NEXT: local.get 0
+; WASM64-NEXT: local.get 5
+; WASM64-NEXT: i64.load 16
+; WASM64-NEXT: i64.store 0
+; WASM64-NEXT: local.get 5
+; WASM64-NEXT: i64.const 64
+; WASM64-NEXT: i64.add
+; WASM64-NEXT: global.set __stack_pointer
+; WASM64-NEXT: # fallthrough-return
+ %result = call { <2 x fp128>, <2 x fp128> } @llvm.sincos.v2f128(<2 x fp128> %a)
+ ret { <2 x fp128>, <2 x fp128> } %result
+}
attributes #0 = { nounwind }
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The logic here LGTM, can't vouch for the WASM tests though.
a95c091
to
c2d0cd4
Compare
65011f9
to
248eb92
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wasm changes LGTM
6df65a4
to
bb6f24f
Compare
Fix asserting in the error case.
248eb92
to
aceabe9
Compare
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/162/builds/26326 Here is the relevant piece of the build log for the reference
|
Fix asserting in the error case.